/**********************************************************************
* Filename: Individual.java
* Created: 2013/05/30
* @author Fernando Brito e Abreu
**********************************************************************/
package org.quasar.airNova.businessLayer;

import org.quasar.airNova.persistenceLayer.Database;

import java.util.Set;
import java.util.HashSet;

public class Individual extends Cliente
{
	
	/***********************************************************
	* @return all instances of class Individual
	***********************************************************/
	public static Set<Individual> allInstances()
	{
		return Database.allInstances(Individual.class);
	}
	
	private String email;
	private int n_passaporte;
	private Sexo sexo;
	private int telefone_movel;
	
	/**********************************************************************
	* Default constructor
	**********************************************************************/
	public Individual()
	{
		super();
	}
	
	/**********************************************************************
	* Parameterized constructor
	* @param codigo_cliente the codigo_cliente to initialize (inherited)
	* @param morada the morada to initialize (inherited)
	* @param n_contribuinte the n_contribuinte to initialize (inherited)
	* @param nome the nome to initialize (inherited)
	* @param email the email to initialize
	* @param n_passaporte the n_passaporte to initialize
	* @param sexo the sexo to initialize
	* @param telefone_movel the telefone_movel to initialize
	**********************************************************************/
	public Individual(int codigo_cliente, String morada, int n_contribuinte, String nome, String email, int n_passaporte, Sexo sexo, int telefone_movel)
	{
		super(codigo_cliente, morada, n_contribuinte, nome);
		this.email = email;
		this.n_passaporte = n_passaporte;
		this.sexo = sexo;
		this.telefone_movel = telefone_movel;
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the email of the individual
	**********************************************************************/
	public String email()
	{
		return email;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param email the email to set
	**********************************************************************/
	public void setEmail(String email)
	{
		this.email = email;
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the n_passaporte of the individual
	**********************************************************************/
	public int n_passaporte()
	{
		return n_passaporte;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param n_passaporte the n_passaporte to set
	**********************************************************************/
	public void setN_passaporte(int n_passaporte)
	{
		this.n_passaporte = n_passaporte;
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the sexo of the individual
	**********************************************************************/
	public Sexo sexo()
	{
		return sexo;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param sexo the sexo to set
	**********************************************************************/
	public void setSexo(Sexo sexo)
	{
		this.sexo = sexo;
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the telefone_movel of the individual
	**********************************************************************/
	public int telefone_movel()
	{
		return telefone_movel;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param telefone_movel the telefone_movel to set
	**********************************************************************/
	public void setTelefone_movel(int telefone_movel)
	{
		this.telefone_movel = telefone_movel;
	}
	
	/**********************************************************************
	* MANY2MANY getter for Individual[*] <-> Pais[*]
	* @return the nacionalidade of the nacionais
	**********************************************************************/
	public Set<Pais> nacionalidade()
	{
		Set<Pais> result = new HashSet<Pais>();
		for (Pais x : Pais.allInstances())
			if (x.nacionais() != null && x.nacionais().contains(this))
				result.add(x);
		return result;
	}
	
	/**********************************************************************
	* MANY2MANY multiple setter for Individual[*] <-> Pais[*]
	* @param nacionalidade the nacionalidade to set
	**********************************************************************/
	public void setNacionalidade(Set<Pais> nacionalidade)
	{
		for (Pais x : nacionalidade)
			x.nacionais().add(this);
	}
	
	/**********************************************************************
	* MANY2MANY single setter for Individual[*] <-> Pais[*]
	* @param pais the pais to add
	**********************************************************************/
	public void addNacionalidade(Pais pais)
	{
		pais.addNacionais(this);
	}
	
	/**********************************************************************
	* Object serializer
	**********************************************************************/
	public String toString()
	{
		return "Individual [" + super.toString() + " email=" + email + ", n_passaporte=" + n_passaporte + ", sexo=" + sexo + ", telefone_movel=" + telefone_movel + "]";
	}
	
	//	-------------------------------------------------------------------------------
	//	INVARIANTS (TODO)
	/*
	inv individualComN_PassaporteDefinidoNecessitaDeTerUmPais
		if self.n_passaporte.isDefined then self.nacionalidade->notEmpty else self.nacionalidade->isEmpty endif
	
	inv passaporteUnico
		(self.n_passaporte.isDefined implies Individual.allInstances->forAll(c1 : Individual, c2 : Individual | ((c1 <> c2) implies (c1.n_passaporte <> c2.n_passaporte))))
	
	*/
}
